//
// Created by martin on 2/15/22.
//

#ifndef MUDUO_ACCEPTOR_H
#define MUDUO_ACCEPTOR_H

#include "muduo/base/noncopyable.h"
#include "muduo/net/Socket.h"
#include "muduo/net/Channel.h"

#include <functional>

namespace muduo
{
namespace net
{

class EventLoop;
class InetAddress;

/**
 * TCP连接接受器
 * 基础调用为accept(2)/accept4(2)
 */
class Acceptor : private noncopyable
{
public:
    typedef std::function<void(int sockfd, const InetAddress &)> NewConnectionCallback;

    Acceptor(EventLoop* loop, const InetAddress& listenAddr, bool reuseport);
    ~Acceptor();

    /* 设置新连接回调 */
    void setNewConnectionCallback(const NewConnectionCallback& cb)
    { newConnectionCallback_ = cb; }

    /* 监听本地端口 */
    void listen();

    /* 判断当前是否正在监听端口 */
    bool listening() const { return listening_; }

private:
    void handleRead();       // 处理读事件

    EventLoop *loop_;        // 所属EventLoop
    Socket acceptSocket_;    // 专门用于接受连接的套接字(sock fd)
    Channel acceptChannel_;  // 专门接受连接通道, 监听conn fd
    NewConnectionCallback newConnectionCallback_; // 新建连接回调
    bool listening_;         // 监听状态
    int idleFd_;             // 空闲fd, 用于fd资源不够用时, 可以空一个出来作为新建连接conn fd
};

} // namespace net
} // namespace muduo

#endif //MUDUO_ACCEPTOR_H
